home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume9 / elm2 / part03 < prev    next >
Encoding:
Internet Message Format  |  1987-03-08  |  53.4 KB

  1. Subject:  v09i003:  ELM Mail System, Part03/19
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.TMC.COM
  4.  
  5. Submitted by: Dave Taylor <hplabs!taylor>
  6. Mod.sources: Volume 9, Issue 3
  7. Archive-name: elm2/Part03
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If this archive is complete, you will see the message:
  13. #        "End of archive 3 (of 19)."
  14. # Contents:  Instructions MANIFEST filter/summarize.c hdrs/filter.h
  15. #   hdrs/shortnames.h src/builtin.c src/encode.c src/savecopy.c
  16. #   utils/Makefile utils/Makefile.mstr utils/autoreply.c
  17. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  18. echo shar: Extracting \"Instructions\" \(4676 characters\)
  19. if test -f Instructions ; then 
  20.   echo shar: Will not over-write existing file \"Instructions\"
  21. else
  22. sed "s/^X//" >Instructions <<'END_OF_Instructions'
  23. X
  24. X                Instructions
  25. X                ------------
  26. X
  27. X            Last Update: July 17th, 1986
  28. X
  29. X
  30. X    This file contains instructions on how to create and install
  31. Xthe entire ELM mail system.  It should be read BEFORE any attempts
  32. Xare made at actually creating and/or installing any of the software
  33. Xcontained herein!
  34. X
  35. X    There is actually really one step needed - unpack all the shar
  36. Xfiles and then;
  37. X
  38. X    $ cd <where-ever you're keeping the Elm sources>
  39. X
  40. X    $ sh Configure.sh
  41. X
  42. X    Answer the questions of that program,, then let it create the localized
  43. XMakefiles and system definition files for you.  When it's done you can double
  44. Xcheck the configuration (or customize it further) by reading the Configuration
  45. XGuide + editing the file "hdrs/sysdefs.h".  There are lots of neat features
  46. Xthat are unique to this mailer - it's worth a quick perusal at least!
  47. X
  48. X    Once you're happy with the localized files, you then need to create
  49. Xthe documentation (so there's a bit of a catch-22 that you need to format the
  50. XConfiguration guide before you are happy with the localization but can't do
  51. Xthat until you're happy with the localization...oh well).
  52. X
  53. X    $
  54. X
  55. X    $ make documentation
  56. X
  57. X    When that's done, or even if it fails (don't worry too much about it)
  58. X
  59. X    $ (make -i all >& MAKELOG) &
  60. X    $ tail -f MAKELOG
  61. X
  62. X    (if you're in "sh", you can use "> MAKELOG 2>&1" instead of ">& MAKELOG")
  63. X
  64. XThis will take a fair while, so it's recommended that you go and eat 
  65. Xlunch or play a game for a while!! (alternatively, spend lots of money
  66. Xon a really FAST machine and blink your eyes a few times...)
  67. X
  68. XAssuming there are no errors during compilation (we'll have to assume
  69. Xthat for the moment) you should now be able to list the directory "bin"
  70. Xand find the following files:
  71. X
  72. X    "answer", "arepdaemon", "autoreply", "fastmail", "from", 
  73. X    "elm", "newalias", "newmail", "printmail", and "readmsg".
  74. X
  75. Xnext, you can install all the software on your system by;
  76. X
  77. X    $ make -i install
  78. X    
  79. XNote: the mailer runs as setgid mail to have the ability to WRITE
  80. Xto the /usr/mail directory (for lock files).   If you have a different
  81. Xscheme at your site, feel free to set it up to use that instead.
  82. X
  83. XFinally, we're just about done!   The final checks can be made
  84. Xby the following commands:
  85. X
  86. X    $ /usr/local/bin/elm -z
  87. X
  88. Xshould say "no mail" if nothing's in your incoming mailbox, and
  89. X
  90. X    $ /usr/local/bin/elm -f test/test.mail
  91. X
  92. Xshould read in EIGHT messages from various people.  While here, try to
  93. XA)lias C)urrent message for each of the eight messages to confirm that
  94. Xthe reply/address system is working okay.   Now try to C)hange mailboxes
  95. Xto the file "test/test.note" and use the '%' key to see if the mailer is
  96. Xgenerating valid return addresses for the notes (If not, then you might
  97. Xneed to install the pathalias database - see "sysdefs.h" for more info)
  98. XChange back to "test/test.mail" and Q)uit without having marked anything 
  99. Xfor deletion...answer the questions accordingly.
  100. X
  101. XIf you get this far you're in Wonderful shape!  In fact, you're done!
  102. X
  103. XCongratulations!  You've just installed one of the best electronic mail
  104. Xsystems available today on your machine (if I say so myself!)
  105. X
  106. XHANDY HINTS:  If you want to create a print of the entire set of
  107. Xsources, including this file, use the command:
  108. X
  109. X    $ make listing
  110. X
  111. XIf, on the other hand, you just want to create a listing file of 
  112. Xjust the ELM sources, try:
  113. X
  114. X    $ make elm-listing
  115. X
  116. XAlso, if you have a number of machines on a network, you can rlogin
  117. Xto the remote machine and then do a remote install (after checking
  118. Xto ensure that the networking copy method in the Makefile under the
  119. Xtarget "remote-install" is correct) by typing:
  120. X
  121. X    $ make -f <remote Makefile> REMOTE=<remote file system> rmt-install
  122. X
  123. X(for example, if we had installed the system on machine "machx" and 
  124. X wanted to install it on "machy", with the Makefile in /src/Elm on
  125. X "machx", we could type from "machy";
  126. X     $ make -f machx:/src/Elm/Makefile REMOTE=machx: rmt-install
  127. X to have it install the system on machine y!)
  128. X
  129. XOne final note for non-US distribution - the program might complain
  130. Xat link time that it can't find "crypt()".  If so, and if you cannot
  131. Xobtain a copy, you should merely instruct your users to not use the
  132. Xencrypted mail option on outgoing mail.
  133. X
  134. XThat's it!
  135. X----------
  136. X
  137. XOh!  One final note: if you'd like a nicely typeset copy of the documentation,
  138. Xfeel free to drop me a line with your full (overland) mail address!!  I'll
  139. Xtry to get it back to you within a week or two.
  140. X
  141. X-----------
  142. X
  143. X    Author's address:    taylor@HPLABS
  144. X                hplabs!taylor
  145. X
  146. X    Mail address:        Dave Taylor
  147. X                Hewlett Packard Laboratories
  148. X                1501 Page Mill Road
  149. X                Palo Alto CA
  150. X                94304
  151. X
  152. X  This document and the entire mail system is
  153. X
  154. X    (C) Copyright 1986, Dave Taylor
  155. END_OF_Instructions
  156. if test 4676 -ne `wc -c <Instructions`; then
  157.     echo shar: \"Instructions\" unpacked with wrong size!?
  158. fi
  159. # end of overwriting check
  160. fi
  161. echo shar: Extracting \"MANIFEST\" \(4296 characters\)
  162. if test -f MANIFEST ; then 
  163.   echo shar: Will not over-write existing file \"MANIFEST\"
  164. else
  165. sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
  166. X   File Name        Archive #    Description
  167. X-----------------------------------------------------------
  168. X Configure.sh             18    
  169. X Instructions              3    
  170. X MANIFEST                  3    
  171. X Makefile                  9    
  172. X Makefile.mstr             9    
  173. X NOTICE                    2    
  174. X Overview                  4    
  175. X bin                       1    
  176. X doc                       1    
  177. X doc/Alias.guide          15    
  178. X doc/Config.guide         15    
  179. X doc/Elm.coversheet        1    
  180. X doc/Filter.guide         14    
  181. X doc/Form.guide           10    
  182. X doc/Ref.guide            19    
  183. X doc/Users.guide          18    
  184. X doc/answer.1              1    
  185. X doc/autoreply.1           1    
  186. X doc/checkalias.1          1    
  187. X doc/elm-help.0            1    
  188. X doc/elm-help.1            1    
  189. X doc/elm-help.2            1    
  190. X doc/elm.1                 2    
  191. X doc/elmrc-info            2    
  192. X doc/elmrc.sample          1    
  193. X doc/fastmail.1            2    
  194. X doc/filter.1              1    
  195. X doc/from.1                1    
  196. X doc/listalias.1           1    
  197. X doc/messages.1            1    
  198. X doc/newalias.1            1    
  199. X doc/newmail.1             1    
  200. X doc/printmail.1           1    
  201. X doc/readmsg.1             2    
  202. X doc/trim-headers.1        1    
  203. X doc/wnewmail.1            1    
  204. X filter                    1    
  205. X filter/Makefile           1    
  206. X filter/Makefile.mstr      1    
  207. X filter/actions.c          5    
  208. X filter/filter.c           4    
  209. X filter/parse.c            8    
  210. X filter/rules.c            5    
  211. X filter/summarize.c        3    
  212. X filter/utils.c            2    
  213. X filter/utils2.c           4    
  214. X hdrs                      1    
  215. X hdrs/curses.h             1    
  216. X hdrs/defs.h               6    
  217. X hdrs/elm.h                5    
  218. X hdrs/filter.h             3    
  219. X hdrs/headers.h            5    
  220. X hdrs/save_opts.h          1    
  221. X hdrs/shortnames.h         3    
  222. X hdrs/sysdefs.h            6    
  223. X hdrs/sysdefs.master       6    
  224. X hdrs/sysdefs.old          6    
  225. X src                       1    
  226. X src/Makefile              2    
  227. X src/Makefile.mstr         2    
  228. X src/addr_utils.c         15    
  229. X src/alias.c              10    
  230. X src/aliasdb.c             7    
  231. X src/aliaslib.c            4    
  232. X src/args.c                2    
  233. X src/bounceback.c          2    
  234. X src/builtin.c             3    
  235. X src/calendar.c            5    
  236. X src/connect_to.c          2    
  237. X src/curses.c             16    
  238. X src/curses.q             12    
  239. X src/date.c               10    
  240. X src/delete.c              1    
  241. X src/domains.c             7    
  242. X src/edit.c                4    
  243. X src/editmsg.c            12    
  244. X src/elm.c                17    
  245. X src/encode.c              3    
  246. X src/errno.c               2    
  247. X src/file.c                6    
  248. X src/file_utils.c          4    
  249. X src/fileio.c              2    
  250. X src/forms.c               9    
  251. X src/getopt.c              1    
  252. X src/hdrconfg.c            5    
  253. X src/help.c                5    
  254. X src/initialize.c          7    
  255. X src/initialize.uts        6    
  256. X src/input_utils.c         8    
  257. X src/leavembox.c          12    
  258. X src/limit.c               6    
  259. X src/mailmsg1.c            8    
  260. X src/mailmsg2.c           17    
  261. X src/mailtime.c            4    
  262. X src/mkhdrs.c              2    
  263. X src/newmbox.c            14    
  264. X src/opt_utils.c           4    
  265. X src/options.c             8    
  266. X src/output_utils.c        1    
  267. X src/pattern.c             5    
  268. X src/pmalloc.c             1    
  269. X src/quit.c                1    
  270. X src/read_rc.c            16    
  271. X src/remail.c              1    
  272. X src/reply.c              14    
  273. X src/return_addr.c         9    
  274. X src/save_opts.c           9    
  275. X src/savecopy.c            3    
  276. X src/screen.c             11    
  277. X src/screen3270.q         11    
  278. X src/showmsg.c            11    
  279. X src/showmsg_cmd.c         2    
  280. X src/signals.c             1    
  281. X src/softkeys.c            2    
  282. X src/sort.c                4    
  283. X src/string2.c             1    
  284. X src/strings.c            11    
  285. X src/syscall.c             4    
  286. X src/utils.c               5    
  287. X src/validname.c           1    
  288. X test                      1    
  289. X test/test.empty           1    
  290. X test/test.mail           10    
  291. X test/test.notes          13    
  292. X utils                     1    
  293. X utils/Makefile            3    
  294. X utils/Makefile.mstr       3    
  295. X utils/answer.c            8    
  296. X utils/arepdaemon.c       13    
  297. X utils/autoreply.c         3    
  298. X utils/fastmail.c          7    
  299. X utils/from.c             10    
  300. X utils/listalias.c         1    
  301. X utils/mailrc.awk          1    
  302. X utils/newalias.c         13    
  303. X utils/newmail.c           7    
  304. X utils/printmail.c         2    
  305. X utils/readmsg.c          12    
  306. X utils/trim-headers        1    
  307. X utils/wnewmail.c          7    
  308. END_OF_MANIFEST
  309. if test 4296 -ne `wc -c <MANIFEST`; then
  310.     echo shar: \"MANIFEST\" unpacked with wrong size!?
  311. fi
  312. # end of overwriting check
  313. fi
  314. echo shar: Extracting \"filter/summarize.c\" \(4658 characters\)
  315. if test -f filter/summarize.c ; then 
  316.   echo shar: Will not over-write existing file \"filter/summarize.c\"
  317. else
  318. sed "s/^X//" >filter/summarize.c <<'END_OF_filter/summarize.c'
  319. X/**            summarize.c            **/
  320. X
  321. X/** This routine is called from the filter program (or can be called
  322. X    directly with the correct arguments) and summarizes the users filterlog
  323. X    file.  To be honest, there are two sorts of summaries that are
  324. X    available - either the '.filterlog' file can be output (filter -S) 
  325. X    or a summary by rule and times acted upon can be output (filter -s).
  326. X    Either way, this program will delete the two associated files each
  327. X    time ($HOME/.filterlog and $HOME/.filtersum) *if* the -c option is
  328. X    used to the program (e.g. clear_logs is set to TRUE).
  329. X
  330. X    (C) Copyright 1986, Dave Taylor
  331. X**/
  332. X
  333. X#include <stdio.h>
  334. X
  335. X#include "defs.h"
  336. X
  337. X#include "filter.h"
  338. X
  339. Xshow_summary()
  340. X{
  341. X    /* Summarize usage of the program... */
  342. X
  343. X    FILE   *fd;                /* for output to temp file! */
  344. X    char filename[SLEN],            /* name of the temp file    */
  345. X         buffer[LONG_SLEN];            /* input buffer space       */
  346. X    int  erroneous_rules = 0,
  347. X         default_rules   = 0,
  348. X         rule,
  349. X         applied[MAXRULES];
  350. X
  351. X    if (long_summary) 
  352. X      long_sum();
  353. X    else {
  354. X
  355. X      sprintf(filename, "%s/%s", home, filtersum);
  356. X
  357. X      if ((fd = fopen(filename, "r")) == NULL) {
  358. X        fprintf(stderr,"filter (%s): Can't open filterlog file %s!\n",
  359. X            username, filename);
  360. X        exit(1);
  361. X      }
  362. X
  363. X      for (rule=0;rule < MAXRULES; rule++)
  364. X        applied[rule] = 0;            /* initialize it all! */
  365. X
  366. X      /** Next we need to read it all in, incrementing by which rule
  367. X          was used.  The format is simple - each line represents a 
  368. X          single application of a rule, or '-1' if the default action
  369. X          was taken.  Simple stuff, eh?  But oftentimes the best.  
  370. X      **/
  371. X
  372. X      while (fgets(buffer, LONG_SLEN, fd) != NULL) {
  373. X        if ((rule = atoi(buffer)) > total_rules || rule < -1) {
  374. X          fprintf(stderr,
  375. X      "%sfilter (%s): Warning - rule #%d is invalid data for short summary!!\n",
  376. X             BEEP, username, rule);
  377. X          erroneous_rules++;
  378. X        }
  379. X        else if (rule == -1)
  380. X          default_rules++;
  381. X        else
  382. X          applied[rule]++;
  383. X      }
  384. X    
  385. X      fclose(fd);
  386. X
  387. X      /** now let's summarize the data... **/
  388. X
  389. X      printf("\nSummary of filter activity;\n\n");
  390. X
  391. X      if (erroneous_rules)
  392. X        printf("** Warning: %d erroneous rule%s logged and ignored! **\n\n",
  393. X           erroneous_rules, erroneous_rules > 1? "s were" : " was");
  394. X    
  395. X      if (default_rules)
  396. X        printf(
  397. X   "The default rule of putting mail into your mailbox was used %d time%s\n\n",
  398. X           default_rules, plural(default_rules));
  399. X
  400. X      /** and now for each rule we used... **/
  401. X
  402. X      for (rule = 0; rule < total_rules; rule++) {
  403. X        if (applied[rule]) {
  404. X           printf("Rule #%d: ", rule+1);
  405. X           switch (rules[rule].action) {
  406. X          case LEAVE:    printf("(leave mail in mailbox)");    break;
  407. X          case DELETE:  printf("(delete message)");        break;
  408. X          case SAVE  :  printf("(save in \"%s\")",
  409. X                    rules[rule].argument2);        break;
  410. X          case SAVECC:  printf("(left in mailbox and saved in \"%s\")",
  411. X                    rules[rule].argument2);        break;
  412. X          case FORWARD: printf("(forwarded to \"%s\")",
  413. X                    rules[rule].argument2);        break;
  414. X          case EXEC  :  printf("(given to command \"%s\")",
  415. X                    rules[rule].argument2);        break;
  416. X           }
  417. X           printf(" was applied %d time%s.\n\n", applied[rule],
  418. X              plural(applied[rule]));
  419. X         }
  420. X       }
  421. X
  422. X      /* next, after a ^L, include the actual log file... */
  423. X
  424. X      sprintf(filename, "%s/%s", home, filterlog);
  425. X
  426. X      if ((fd = fopen(filename, "r")) == NULL) {
  427. X        fprintf(stderr,"filter (%s): Can't open filterlog file %s!\n",
  428. X            username, filename);
  429. X      }
  430. X      else {
  431. X        printf("\n\n\n%c\n\nExplicit log of each action;\n\n", (char) 12);
  432. X        while (fgets(buffer, LONG_SLEN, fd) != NULL)
  433. X          printf("%s", buffer);
  434. X        printf("\n-----\n");
  435. X        fclose(fd);
  436. X      }
  437. X
  438. X      /* now remove the log files, please! */
  439. X
  440. X      if (clear_logs) {
  441. X        unlink(filename);
  442. X        sprintf(filename, "%s/%s", home, filtersum);
  443. X        unlink(filename);
  444. X      }
  445. X
  446. X      return;
  447. X    }
  448. X}
  449. X
  450. Xlong_sum()
  451. X{
  452. X    /** summarize by listing the .fitlerlog file.  The simplest of the
  453. X        two possible options this one is indeed rather trivial!  **/
  454. X
  455. X    FILE   *fd;                /* for output to temp file! */
  456. X    char filename[SLEN],            /* name of the temp file    */
  457. X         buffer[LONG_SLEN];            /* input buffer space       */
  458. X
  459. X    sprintf(filename,"%s/%s", home, filterlog);
  460. X
  461. X    if ((fd = fopen(filename, "r")) == NULL) {
  462. X      fprintf(stderr,"filter (%s): Can't open filterlog file %s!\n",
  463. X          username, filename);
  464. X      exit(1);
  465. X    }
  466. X
  467. X    while (fgets(buffer, SLEN, fd) != NULL)
  468. X      printf("%s", buffer);    /* already has '\n' doesn't it? */
  469. X    fclose(fd);
  470. X
  471. X    /** now let's waste the TWO log files and get outta here! **/
  472. X
  473. X    if (clear_logs) {
  474. X      unlink(filename);
  475. X      sprintf(filename, "%s/%s", home, filtersum);
  476. X      unlink(filename);
  477. X    }
  478. X
  479. X    return;
  480. X}
  481. END_OF_filter/summarize.c
  482. if test 4658 -ne `wc -c <filter/summarize.c`; then
  483.     echo shar: \"filter/summarize.c\" unpacked with wrong size!?
  484. fi
  485. # end of overwriting check
  486. fi
  487. echo shar: Extracting \"hdrs/filter.h\" \(3994 characters\)
  488. if test -f hdrs/filter.h ; then 
  489.   echo shar: Will not over-write existing file \"hdrs/filter.h\"
  490. else
  491. sed "s/^X//" >hdrs/filter.h <<'END_OF_hdrs/filter.h'
  492. X/**            filter.h            **/
  493. X
  494. X/** Headers for the filter program.
  495. X
  496. X   (C) Copyright 1986, Dave Taylor
  497. X**/
  498. X
  499. X#ifdef   BSD
  500. X# undef  tolower
  501. X# define tolower(c)    (isupper(c)?  c = c - 'A' + 'a' : c)
  502. X#endif
  503. X
  504. X/** define a few handy macros for later use... **/
  505. X
  506. X#define  BEEP        (audible? "\007" : "")
  507. X
  508. X#define  the_same(a,b)    (strncmp(a,b,strlen(b)) == 0)
  509. X
  510. X#define relationname(x)  (x == 1?"<=":x==2?"<":x==3?">=":x==4?">":x==5?"!=":"=")
  511. X
  512. X#define quoteit(x)     (x == LINES? "" : "\"")
  513. X
  514. X/** some of the files we'll be using, where they are, and so on... **/
  515. X
  516. X#define  filter_temp    "/tmp/filter"
  517. X#define  filterfile    ".filter-rules"
  518. X#define  filterlog    ".filterlog"
  519. X#define  filtersum    ".filtersum"
  520. X
  521. X#define  EMERGENCY_MAILBOX    "EMERGENCY_MBOX"
  522. X#define  EMERG_MBOX        "MBOX.EMERGENCY"
  523. X
  524. X/** and now the hardwired constraint of the program.. **/
  525. X
  526. X#define  MAXRULES    25        /* can't have more den dis, boss! */
  527. X
  528. X/** some random defines for mnemonic stuff in the program... **/
  529. X
  530. X#define  TO        1
  531. X#define  FROM        2
  532. X#define  LINES        3
  533. X#define  CONTAINS    4
  534. X
  535. X#define  DELETE     5
  536. X#define  SAVE        6
  537. X#define  SAVECC        7
  538. X#define  FORWARD    8
  539. X#define  LEAVE        9
  540. X#define  EXEC        10
  541. X
  542. X#define  FAILED_SAVE    20
  543. X
  544. X/** Some conditionals... **/
  545. X
  546. X#define LE        1
  547. X#define LT        2
  548. X#define GE        3
  549. X#define GT        4
  550. X#define NE        5
  551. X#define EQ        6
  552. X
  553. X/** A funky way to open a file using open() to avoid file locking hassles **/
  554. X
  555. X#define  FOLDERMODE    O_WRONLY | O_APPEND | O_CREAT | O_SYNCIO
  556. X
  557. X/** cheap but easy way to have two files share the same #include file **/
  558. X
  559. X#ifdef MAIN_ROUTINE
  560. X# define  extern
  561. X#endif
  562. X
  563. Xextern char home[SLEN],                /* the users home directory */
  564. X            hostname[SLEN],            /* the machine name...      */
  565. X            username[SLEN];            /* the users login name...  */
  566. X
  567. Xextern char to[VERY_LONG_STRING], 
  568. X            from[SLEN], 
  569. X            subject[SLEN];            /* from current message     */
  570. X
  571. X#ifdef MAIN_ROUTINE
  572. Xint  total_rules = 0,                /* how many rules to check  */
  573. X     show_only = FALSE,                /* just for show?           */
  574. X     long_summary = FALSE,            /* what sorta summary??     */
  575. X     verbose   = FALSE,                /* spit out lots of stuff   */
  576. X     audible   = FALSE,                /* be noisy with output?    */
  577. X     lines     = 0,                /* lines in message..       */
  578. X     clear_logs = FALSE,            /* clear files after sum?   */
  579. X     already_been_forwarded = FALSE,        /* has this been filtered?  */
  580. X     log_actions_only = FALSE,            /* log actions | everything */
  581. X     rule_choosen;                /* which one we choose      */
  582. X#else
  583. Xextern int total_rules,                /* how many rules to check  */
  584. X           show_only,                /* just for show?           */
  585. X           long_summary,            /* what sorta summary??     */
  586. X           verbose,                /* spit out lots of stuff   */
  587. X           audible,                /* be noisy with output?    */
  588. X           lines,                /* lines in message..       */
  589. X           clear_logs,                    /* clear files after sum?   */
  590. X       already_been_forwarded,        /* has this been filtered?  */
  591. X           log_actions_only,            /* log actions | everything */
  592. X           rule_choosen;            /* which one we choose      */
  593. X#endif
  594. X
  595. X/** and our ruleset record structure... **/
  596. X
  597. Xstruct condition_rec {
  598. X    int     matchwhat;            /* type of 'if' clause      */
  599. X    int     relation;            /* type of match (eq, etc)  */
  600. X    char    argument1[SLEN];        /* match against this       */
  601. X    struct  condition_rec  *next;        /* next condition...        */
  602. X      };
  603. X
  604. Xextern struct ruleset_record {
  605. X    char      printable[SLEN];        /* straight from file...    */
  606. X    struct  condition_rec  *condition;
  607. X    int     action;                /* what action to take      */
  608. X    char    argument2[SLEN];        /* argument for action      */
  609. X      } rules[MAXRULES];
  610. X
  611. X
  612. X/** finally let's keep LINT happy with the return values of all these pups! ***/
  613. X
  614. Xunsigned short getuid();
  615. X
  616. Xunsigned long sleep();
  617. X
  618. Xchar *malloc(), *strcpy(), *strcat(), *itoa();
  619. X
  620. Xvoid    exit();
  621. X
  622. X#ifdef BSD
  623. X    
  624. X  FILE *popen();
  625. X
  626. X  extern char  _vbuf[5*BUFSIZ];        /* space for file buffering */
  627. X
  628. X# define _IOFBF        0        /* doesn't matter - ignored */
  629. X
  630. X# define setvbuf(fd,a,b,c)    setbuffer(fd, _vbuf, 5*BUFSIZ)
  631. X
  632. X#endif
  633. END_OF_hdrs/filter.h
  634. if test 3994 -ne `wc -c <hdrs/filter.h`; then
  635.     echo shar: \"hdrs/filter.h\" unpacked with wrong size!?
  636. fi
  637. # end of overwriting check
  638. fi
  639. echo shar: Extracting \"hdrs/shortnames.h\" \(3969 characters\)
  640. if test -f hdrs/shortnames.h ; then 
  641.   echo shar: Will not over-write existing file \"hdrs/shortnames.h\"
  642. else
  643. sed "s/^X//" >hdrs/shortnames.h <<'END_OF_hdrs/shortnames.h'
  644. X/**            shortnames.h            **/
  645. X
  646. X/** This file is from Geoff Kuenning, and will help those poor users that
  647. X    are stuck using C compilers that don't have flexnames.   Too bad.
  648. X
  649. X    This file has no explicit copyright.
  650. X
  651. X**/
  652. X
  653. X#define PutLine0        PLine0
  654. X#define PutLine1        PLine1
  655. X#define PutLine2        PLine2
  656. X#define PutLine3        PLine3
  657. X
  658. X#define add_to_table        add_2_table
  659. X#define address1        addrs1
  660. X#define addressII        addrsII
  661. X#define addresses        addr_s
  662. X#define alternate_prompt    alt_prompt
  663. X#define alternative_addresses    alt_addrs
  664. X#define always_leave        alw_leave
  665. X
  666. X#define calendar_line        cal_line
  667. X#define cancelled_msg        cncld_msg
  668. X#define central_message_buffer    cntrl_bfr
  669. X#define compare_dates        cmp_dates
  670. X#define compare_headers        cmp_hdrs
  671. X#define copy_message_across    cpy_msg_across
  672. X#define current_record        cur_rec
  673. X#define current_time        cur_time
  674. X
  675. X#define define_softkeys        def_softkeys
  676. X#define display_central_message    displ_cntrl_msg
  677. X#define display_error        displ_error
  678. X#define display_headers        displ_hdrs
  679. X#define display_helpfile    dspl_helpfile
  680. X#define display_options        displ_options
  681. X#define display_title        displ_titles
  682. X#define display_to        displ_to
  683. X
  684. X#define encrypted        crypted
  685. X#define encrypted_key        crypt_key
  686. X#define expanded_cc        xp_cc
  687. X#define expanded_to        xp_to
  688. X#define expand_address        xp_addr
  689. X#define expand_domain        xp_domain
  690. X#define expand_env        xp_env
  691. X#define expand_filename        xp_filename
  692. X#define expand_group        xp_group
  693. X#define expand_logname        xp_logname
  694. X#define expand_site        xp_site
  695. X#define expand_system        xp_system
  696. X
  697. X#define filename2        fn2
  698. X#define forward            forwrd
  699. X
  700. X#define generate_reply_to    gen_reply_to
  701. X#define get_return_name        g_ret_name
  702. X
  703. X#define header_line        h_line
  704. X#define header_page        h_page
  705. X#define headers_per_page    h_per_page
  706. X#define header_table        h_table
  707. X
  708. X#define install_aliases        ins_aliases
  709. X
  710. X#define last_line_loc        last_ln_loc
  711. X
  712. X#define machine_group        mach_group
  713. X#define mailbox_defined        mbox_defined
  714. X#define mailfile_size        mfile_size
  715. X#define message_count        msg_count
  716. X#define message_number        msg_number
  717. X
  718. X#define newaliases        nwaliases
  719. X#define noptimize_return    noret_opt
  720. X#define noptimize_usenet    nousenet_opt
  721. X
  722. X#define optimize_and_add    opt_and_add
  723. X#define optimize_arpa        opt_arpa
  724. X#define optimize_cmplx_arpa    opt_cmplx_arpa
  725. X#define optimize_return        opt_return
  726. X#define optimize_usenet        opt_usenet
  727. X#define optional_arg        opt_arg
  728. X#define optionally_enter    opt_enter
  729. X#define original_cc        orig_cc
  730. X#define original_msg_num    orig_msg_num
  731. X#define original_to        orig_to
  732. X
  733. X#define parse_arguments        pars_arguments
  734. X#define parse_arpa_from        prs_arpa_from
  735. X#define password_entry        pw_entry
  736. X#define pattern_enter        pat_enter
  737. X#define pattern_match        pat_match
  738. X
  739. X#define read_alias_files    rd_alias_files
  740. X#define read_headers        rd_headers
  741. X#define read_rc            rd_rc
  742. X#define read_rc_file        rd_rc_file
  743. X#define received_on_machine    rcvd_on_machine
  744. X#define remove_all        rem_all
  745. X#define remove_first_word    rem_1st_word
  746. X#define remove_domains        rem_domains
  747. X#define remove_header        rem_hdr
  748. X#define remove_user        rem_user
  749. X#define remove_through_ch    rem_thru_ch
  750. X#define reply_to_everyone    repl_to_everyone
  751. X#define resolve_received    rslv_received
  752. X
  753. X#define show_message        shw_message
  754. X#define show_msg        showmsg
  755. X#define show_msg_tag        sh_msg_tag
  756. X#define size_of_pathfd        sz_of_pathfd
  757. X#define softkeys_off        soft_off
  758. X#define softkeys_on        soft_on
  759. X#define subjectbuffer        subjbuff
  760. X#define subject_matches        subj_matches
  761. X#define system_call        sys_call
  762. X#define system_data        sys_data
  763. X#define system_files        sys_files
  764. X#define system_hash_table    sys_hash_table
  765. X#define system_record        sys_record
  766. X
  767. X#define tail_of_string        tl_of_string
  768. X#define talk_to_sys        tlk_to_sys
  769. X#define tempfile        tmpfile
  770. X#define termcap_label        tcap_label
  771. X#define top_of_screen_left    top_left_of_screen
  772. X#define top_of_screen_right    top_right_of_screen
  773. X#define translate_return    xlate_return
  774. X
  775. X#define update_mailtime        upd_mailtime
  776. X#define update_title        upd_title
  777. X#define unexpanded_cc        unexp_cc
  778. X#define unexpanded_to        unexp_to
  779. X
  780. X#define verify_transmission    vfy_xmsn
  781. X
  782. X#define weeding_out        wding_out
  783. END_OF_hdrs/shortnames.h
  784. if test 3969 -ne `wc -c <hdrs/shortnames.h`; then
  785.     echo shar: \"hdrs/shortnames.h\" unpacked with wrong size!?
  786. fi
  787. # end of overwriting check
  788. fi
  789. echo shar: Extracting \"src/builtin.c\" \(4541 characters\)
  790. if test -f src/builtin.c ; then 
  791.   echo shar: Will not over-write existing file \"src/builtin.c\"
  792. else
  793. sed "s/^X//" >src/builtin.c <<'END_OF_src/builtin.c'
  794. X/**            builtin.c        **/
  795. X
  796. X/** This is the built-in pager for displaying messages while in the Elm
  797. X    program.  It's a bare-bones pager with precious few options. The idea
  798. X    is that those systems that are sufficiently slow that using an external
  799. X    pager such as 'more' is too slow, then they can use this!
  800. X
  801. X    Added the following functionality;
  802. X
  803. X    <number>s    skip <number> lines
  804. X    <number>f    forward a page or <number> pages
  805. X    /pattern    skip forward to pattern        
  806. X
  807. X    (C) Copyright 1986, Dave Taylor
  808. X**/
  809. X
  810. X#include "headers.h"
  811. X#include <ctype.h>
  812. X
  813. X#define  BEEP        007        /* ASCII Bell character */
  814. X
  815. X#ifdef BSD
  816. X#  undef tolower
  817. X#endif
  818. X
  819. Xint    lines_put_on_screen = 0,    /* number of lines displayed per screen */
  820. X    lines_displayed = 0,        /* Total number of lines displayed      */
  821. X    total_lines_to_display,        /* total number of lines in message     */
  822. X    lines_to_ignore = 0;        /* for 'f' and 's' functions...         */
  823. X
  824. Xstart_builtin(lines_in_message)
  825. Xint lines_in_message;
  826. X{
  827. X    /** clears that screen and resets it's internal counters... **/
  828. X
  829. X    dprint1(8,"displaying %d lines from message using internal pager\n",
  830. X        lines_in_message);
  831. X
  832. X    lines_displayed = 0;
  833. X    lines_put_on_screen = 0;
  834. X    lines_to_ignore = 0;
  835. X
  836. X    total_lines_to_display = lines_in_message;
  837. X}
  838. X
  839. Xint
  840. Xdisplay_line(line)
  841. Xchar *line;
  842. X{
  843. X    /** Display the given line on the screen, taking into account such
  844. X        dumbness as wraparound and such.  If displaying this would put
  845. X        us at the end of the screen, put out the "MORE" prompt and wait
  846. X        for some input.   Return non-zero if the user terminates the
  847. X        paging (e.g. 'q') or zero if we should continue...
  848. X    **/
  849. X    
  850. X    register int lines_needed, okay_char, ch, len = 12, iteration = 0;
  851. X    char     pattern[SLEN];
  852. X
  853. X    if (lines_to_ignore != 0) {
  854. X       if (--lines_to_ignore <= 0) {
  855. X         putchar('\n');
  856. X         lines_to_ignore = 0;
  857. X       }
  858. X       return(0);
  859. X    }
  860. X
  861. X    lines_needed = (int) (printable_chars(line)/COLUMNS); /* wraparound */
  862. X
  863. X    for (ch = 0; ch < strlen(line); ch++)
  864. X      if (line[ch] == '\n') lines_needed++;
  865. X
  866. X    if (lines_needed + lines_put_on_screen > LINES-1) {
  867. X      StartBold();
  868. X      if (user_level == 0) {
  869. X        Write_to_screen(
  870. X               "You've read %d%%: press <space> for more, or 'q' to return", 1,
  871. X        (int) (100.0 * (
  872. X           (float) lines_displayed / (float) total_lines_to_display)));
  873. X        len = 59;
  874. X      }
  875. X      else if (user_level == 1) {
  876. X        Write_to_screen( 
  877. X        "More (%d%%) Press <space> for more, 'q' to return", 1, 
  878. X        (int) (100.0 * (
  879. X           (float) lines_displayed / (float) total_lines_to_display)));
  880. X        len = 49;
  881. X      }
  882. X      else 
  883. X        Write_to_screen(" More (%d%%)", 1, 
  884. X        (int) (100.0 * (
  885. X           (float) lines_displayed / (float) total_lines_to_display)));
  886. X
  887. X      EndBold();
  888. X      okay_char = FALSE;
  889. X      do {
  890. X         Raw(ON);
  891. X         ch =  tolower(ReadCh());
  892. X         Raw(OFF);
  893. Xloop_top:     switch (ch) {
  894. X           case '\n' : 
  895. X           case '\r' : /* <return> pressed... */
  896. X               lines_put_on_screen -= lines_needed;
  897. X               okay_char = TRUE;
  898. X               break;
  899. X           case ' '  : /* <space> pressed... */
  900. X               lines_put_on_screen = 0;
  901. X               okay_char = TRUE;
  902. X               break;
  903. X           case '/'  : putchar('/');fflush(stdout);
  904. X               Raw(ON);
  905. X               optionally_enter(pattern,-1,-1,FALSE);
  906. X               Raw(OFF);
  907. X               CursorLeft(len+strlen(pattern)+1); CleartoEOLN();
  908. X               printf("...searching for pattern \"%s\"...",
  909. X                  pattern);
  910. X               fflush(stdout);
  911. X               break;
  912. X           case 'f'  : lines_to_ignore = ((iteration?iteration:1)*LINES)-5;    
  913. X               CursorLeft(len); CleartoEOLN();
  914. X               printf("...skipping %d lines...",lines_to_ignore+2); 
  915. X               fflush(stdout);
  916. X               lines_put_on_screen = 0;
  917. X               return(0);
  918. X           case 's'  : lines_to_ignore = (iteration?iteration-1:0);
  919. X               CursorLeft(len); CleartoEOLN();
  920. X               if (lines_to_ignore)
  921. X                printf("...skipping %d lines...",lines_to_ignore+1);
  922. X               else
  923. X                printf("...skipping one line...\n");
  924. X               fflush(stdout);
  925. X               lines_put_on_screen = 0;
  926. X               return(0);
  927. X           case 'q'  :
  928. X           case 'Q'  : return(TRUE);    /* get OUTTA here! */
  929. X           default   : if (isdigit(ch)) {
  930. X                     Raw(ON);
  931. X                 do {
  932. X                   iteration = 10*iteration + (ch - '0');
  933. X                 } while (isdigit(ch = ReadCh()));
  934. X                 Raw(OFF);
  935. X                         goto loop_top;    
  936. X               }
  937. X               putchar(BEEP);    
  938. X               fflush(stdout);
  939. X               break;
  940. X         }
  941. X      } while (! okay_char);
  942. X
  943. X      CursorLeft(len);        /* back up to the beginning of line */
  944. X      CleartoEOLN();
  945. X    }
  946. X
  947. X    Write_to_screen("%s", 1, line);
  948. X
  949. X    lines_displayed     += 1;           /* tossed on screen */
  950. X    lines_put_on_screen += lines_needed;       /* read from file   */
  951. X
  952. X    return (FALSE);
  953. X}
  954. END_OF_src/builtin.c
  955. if test 4541 -ne `wc -c <src/builtin.c`; then
  956.     echo shar: \"src/builtin.c\" unpacked with wrong size!?
  957. fi
  958. # end of overwriting check
  959. fi
  960. echo shar: Extracting \"src/encode.c\" \(4300 characters\)
  961. if test -f src/encode.c ; then 
  962.   echo shar: Will not over-write existing file \"src/encode.c\"
  963. else
  964. sed "s/^X//" >src/encode.c <<'END_OF_src/encode.c'
  965. X/**        encode.c        **/
  966. X
  967. X/** This is a heavily mangled version of the 'cypher' program written by
  968. X    person or persons unknown.  
  969. X
  970. X    (C) Copyright 1986, Dave Taylor
  971. X**/
  972. X
  973. X#include <stdio.h>
  974. X#include "curses.h"
  975. X#include "headers.h"
  976. X
  977. X#define RS    94
  978. X#define RN    4
  979. X#define RMASK    0x7fff    /* use only 15 bits */
  980. X
  981. Xstatic char r[RS][RN];        /* rotors */
  982. Xstatic char ir[RS][RN];        /* inverse rotors */
  983. Xstatic char h[RS];        /* half rotor */
  984. Xstatic char s[RS];        /* shuffle vector */
  985. Xstatic int  p[RN];        /* rotor indices */
  986. X
  987. Xstatic char the_key[SLEN];    /* unencrypted key */
  988. Xstatic char *encrypted_key;    /* encrypted key   */
  989. X
  990. Xchar *getpass(), *strncpy(), *strcpy();
  991. Xunsigned long sleep();
  992. X
  993. Xgetkey(send)
  994. Xint send;
  995. X{
  996. X    /** this routine prompts for and returns an encode/decode
  997. X        key for use in the rest of the program.  If send == 1
  998. X        then need to mess with rawmode. **/
  999. X
  1000. X    char buffer[NLEN];
  1001. X    int gotkey = 0, x, y;
  1002. X
  1003. X    GetXYLocation(&x,&y);
  1004. X
  1005. X    ClearLine(21);
  1006. X
  1007. X    if (send) Raw(OFF);
  1008. X
  1009. X    while ( !gotkey ) {
  1010. X      MoveCursor(LINES-1,0);
  1011. X      ClearLine(LINES-1);
  1012. X      if (send)
  1013. X        strcpy( buffer, getpass( "Enter encryption key: "));
  1014. X      else
  1015. X        strcpy( buffer, getpass( "Enter decryption key: "));
  1016. X      MoveCursor(LINES-1,0);
  1017. X      if ( strcmp( buffer, getpass( "Please enter it again: "))) {
  1018. X        error("Your keys were not the same!");
  1019. X        sleep(1);
  1020. X        clear_error();
  1021. X        continue;
  1022. X      }
  1023. X      strcpy(the_key, buffer);    /* save unencrypted key */
  1024. X      makekey( buffer );
  1025. X      gotkey = 1;
  1026. X    }
  1027. X
  1028. X    if (send) Raw(ON);
  1029. X
  1030. X    setup();        /** initialize the rotors etc. **/
  1031. X
  1032. X    ClearLine(LINES-1);        
  1033. X    clear_error();
  1034. X
  1035. X    MoveCursor(x+1,0);    /* move to 'next' line... */
  1036. X}
  1037. X
  1038. Xget_key_no_prompt()
  1039. X{
  1040. X    /** This performs the same action as get_key, but assumes that
  1041. X        the current value of 'the_key' is acceptable.  This is used
  1042. X        when a message is encrypted twice... **/
  1043. X
  1044. X    char buffer[SLEN];
  1045. X
  1046. X    strcpy(buffer, the_key);
  1047. X
  1048. X    makekey( buffer );
  1049. X
  1050. X    setup();
  1051. X}
  1052. X
  1053. Xencode(line)
  1054. Xchar *line;
  1055. X{
  1056. X    /** encrypt or decrypt the specified line.  Uses the previously
  1057. X        entered key... **/
  1058. X
  1059. X    register int i, index, j, ph = 0;
  1060. X
  1061. X    for (index=0; index < strlen(line); index++) {
  1062. X      i = (int) line[index];
  1063. X
  1064. X      if ( (i >= ' ') && (i < '~') ) {
  1065. X        i -= ' ';
  1066. X
  1067. X        for ( j = 0; j < RN; j++ )        /* rotor forwards */
  1068. X          i = r[(i+p[j])%RS][j];
  1069. X
  1070. X        i = ((h[(i+ph)%RS])-ph+RS)%RS;    /* half rotor */
  1071. X
  1072. X        for ( j--  ; j >= 0; j-- )        /* rotor backwards */
  1073. X          i = (ir[i][j]+RS-p[j])%RS;
  1074. X
  1075. X        j = 0;                /* rotate rotors */
  1076. X        p[0]++;
  1077. X        while ( p[j] == RS ) {
  1078. X          p[j] = 0;
  1079. X          j++;
  1080. X          if ( j == RN ) break;
  1081. X          p[j]++;
  1082. X            }
  1083. X  
  1084. X        if ( ++ph == RS )
  1085. X          ph = 0;
  1086. X
  1087. X        i += ' ';
  1088. X      }
  1089. X      
  1090. X      line[index] = (char) i;    /* replace with altered one */
  1091. X    }
  1092. X}
  1093. X
  1094. X
  1095. Xmakekey( rkey)
  1096. Xchar *rkey;
  1097. X{
  1098. X    /** encrypt the key using the system routine 'crypt' **/
  1099. X
  1100. X    char key[8], salt[2], *crypt();
  1101. X
  1102. X    strncpy( key, rkey, 8);
  1103. X    salt[0] = key[0];
  1104. X    salt[1] = key[1];
  1105. X    encrypted_key = crypt( key, salt);
  1106. X}
  1107. X
  1108. X/*
  1109. X * shuffle rotors.
  1110. X * shuffle each of the rotors indiscriminately.  shuffle the half-rotor
  1111. X * using a special obvious and not very tricky algorithm which is not as
  1112. X * sophisticated as the one in crypt(1) and Oh God, I'm so depressed.
  1113. X * After all this is done build the inverses of the rotors.
  1114. X */
  1115. X
  1116. Xsetup()
  1117. X{
  1118. X    register long i, j, k, temp;
  1119. X    long seed;
  1120. X
  1121. X    for ( j = 0; j < RN; j++ ) {
  1122. X        p[j] = 0;
  1123. X        for ( i = 0; i < RS; i++ )
  1124. X            r[i][j] = i;
  1125. X    }
  1126. X
  1127. X    seed = 123;
  1128. X    for ( i = 0; i < 13; i++)        /* now personalize the seed */
  1129. X      seed = (seed*encrypted_key[i] + i) & RMASK;
  1130. X
  1131. X    for ( i = 0; i < RS; i++ )        /* initialize shuffle vector */
  1132. X      h[i] = s[i] = i;
  1133. X
  1134. X    for ( i = 0; i < RS; i++) {        /* shuffle the vector */
  1135. X      seed = (5 * seed + encrypted_key[i%13]) & RMASK;;
  1136. X      k = ((seed % 65521) & RMASK) % RS;
  1137. X      temp = s[k];
  1138. X      s[k] = s[i];
  1139. X      s[i] = temp;
  1140. X    }
  1141. X
  1142. X    for ( i = 0; i < RS; i += 2 ) {    /* scramble the half-rotor */
  1143. X      temp = h[s[i]];            /* swap rotor elements ONCE */
  1144. X      h[s[i]] = h[s[i+1]];
  1145. X      h[s[i+1]] = temp;
  1146. X    }
  1147. X
  1148. X    for ( j = 0; j < RN; j++) {            /* select a rotor */
  1149. X
  1150. X      for ( i = 0; i < RS; i++) {        /* shuffle the vector */
  1151. X        seed = (5 * seed + encrypted_key[i%13]) & RMASK;;
  1152. X        k = ((seed % 65521) & RMASK) % RS;
  1153. X        temp = r[i][j];
  1154. X        r[i][j] = r[k][j];
  1155. X        r[k][j] = temp;
  1156. X      }
  1157. X
  1158. X      for ( i = 0; i < RS; i++)         /* create inverse rotors */
  1159. X        ir[r[i][j]][j] = i;
  1160. X       }
  1161. X}
  1162. END_OF_src/encode.c
  1163. if test 4300 -ne `wc -c <src/encode.c`; then
  1164.     echo shar: \"src/encode.c\" unpacked with wrong size!?
  1165. fi
  1166. # end of overwriting check
  1167. fi
  1168. echo shar: Extracting \"src/savecopy.c\" \(4180 characters\)
  1169. if test -f src/savecopy.c ; then 
  1170.   echo shar: Will not over-write existing file \"src/savecopy.c\"
  1171. else
  1172. sed "s/^X//" >src/savecopy.c <<'END_OF_src/savecopy.c'
  1173. X/**             savecopy.c            **/
  1174. X
  1175. X/** Save a copy of the specified message in the users savemail mailbox.
  1176. X
  1177. X         (C) Copyright 1986, Dave Taylor                    
  1178. X**/
  1179. X
  1180. X#include "headers.h"
  1181. X#ifdef BSD
  1182. X# ifdef BSD4.1
  1183. X#  include <time.h>
  1184. X# else
  1185. X#  include <sys/time.h>
  1186. X# endif
  1187. X#else
  1188. X#  include <time.h>
  1189. X#endif
  1190. X
  1191. X#include <errno.h>
  1192. X
  1193. Xchar *format_long(), *get_arpa_date();
  1194. Xchar *error_name(), *error_description();
  1195. Xchar *ctime();
  1196. X
  1197. Xextern char in_reply_to[SLEN];    /* In-Reply-To: string */
  1198. Xextern int gotten_key;        /* for encryption      */
  1199. Xextern int errno;
  1200. X
  1201. Xchar *strcat(), *strcpy();
  1202. Xunsigned long sleep();
  1203. Xlong  time();
  1204. X
  1205. Xsave_copy(subject, to, cc, filename, original_to)
  1206. Xchar *subject, *to, *cc, *filename, *original_to;
  1207. X{
  1208. X    /** This routine appends a copy of the outgoing message to the
  1209. X        file specified by the SAVEFILE environment variable.  **/
  1210. X
  1211. X    FILE *save,        /* file id for file to save to */
  1212. X         *message;        /* the actual message body     */
  1213. X    long  thetime,        /* variable holder for time    */
  1214. X          time();
  1215. X    char  buffer[SLEN],    /* read buffer                */
  1216. X          savename[SLEN],    /* name of file saving into    */
  1217. X          newbuffer[SLEN];  /* first name in 'to' line     */
  1218. X    register int i;        /* for chopping 'to' line up   */
  1219. X    int   crypted=0;    /* are we encrypting?          */
  1220. X
  1221. X    savename[0] = '\0';
  1222. X
  1223. X    if (save_by_name) {
  1224. X      get_return_name(to, buffer, FALSE);
  1225. X      if (strlen(buffer) == 0) {
  1226. X        dprint1(3,"Warning: get_return_name couldn't break down %s\n", to);
  1227. X        savename[0] = '\0';
  1228. X      }
  1229. X      else {
  1230. X        sprintf(savename, "%s%s%s", folders, 
  1231. X                lastch(folders) == '/'? "" : "/", buffer);
  1232. X
  1233. X        if (can_access(savename, READ_ACCESS) != 0)
  1234. X          savename[0] = '\0';
  1235. X      }
  1236. X    }
  1237. X
  1238. X    if (strlen(savename) == 0) {
  1239. X      if (strlen(savefile) == 0)
  1240. X        return(error("variable 'SAVEFILE' not defined!"));
  1241. X      strcpy(savename, savefile);
  1242. X    }
  1243. X
  1244. X    if ((errno = can_access(savename, WRITE_ACCESS))) {
  1245. X      dprint0(2,"Error: attempt to autosave to a file that can't...\n");
  1246. X      dprint1(2,"\tbe appended to: %s (save_copy)\n", savename);
  1247. X      dprint2(2,"** %s - %s **\n", error_name(errno),
  1248. X          error_description(errno));
  1249. X      error1("permission to append to %s denied!", savename);
  1250. X      sleep(2);
  1251. X      return(FALSE);
  1252. X    }
  1253. X
  1254. X    if ((save = fopen(savename, "a")) == NULL) {
  1255. X      dprint2(1,"Error: Couldn't append message to file %s (%s)\n",
  1256. X          savename, "save_copy");
  1257. X      dprint2(1,"** %s - %s **\n", error_name(errno),
  1258. X          error_description(errno));
  1259. X      error1("couldn't append to %s", savename);
  1260. X      sleep(2);
  1261. X      return(FALSE);
  1262. X    }
  1263. X
  1264. X    if ((message = fopen(filename, "r")) == NULL) {
  1265. X      fclose(save);
  1266. X      dprint1(1,"Error: Couldn't read file %s (save_copy)\n", filename);
  1267. X      dprint2(1,"** %s - %s **\n", error_name(errno),
  1268. X          error_description(errno));
  1269. X      error1("couldn't read file %s!", filename);
  1270. X      sleep(2);
  1271. X      return(FALSE);
  1272. X    }
  1273. X
  1274. X    for (i=0; original_to[i] != '\0' && ! whitespace(original_to[i]); i++)
  1275. X      newbuffer[i] = original_to[i];
  1276. X
  1277. X    newbuffer[i] = '\0';
  1278. X
  1279. X    tail_of(newbuffer, buffer, FALSE);
  1280. X
  1281. X    thetime = time((long *) 0);      /* dumb dumb dumb routine */
  1282. X
  1283. X    fprintf(save,"\nFrom To:%s %s", buffer, ctime(&thetime));
  1284. X
  1285. X    fprintf(save, "Date: %s\n", get_arpa_date());
  1286. X            
  1287. X    fprintf(save,"To: %s\nSubject: %s\n", 
  1288. X        format_long(to,strlen("To: ")), subject);
  1289. X
  1290. X    if (strlen(cc) > 0)
  1291. X      fprintf(save,"Cc: %s\n", 
  1292. X          format_long(cc, strlen("Cc:")));
  1293. X
  1294. X    if (strlen(in_reply_to) > 0)
  1295. X      fprintf(save, "In-Reply-To: %s\n", in_reply_to);
  1296. X
  1297. X    (void) putc('\n', save);    /* put another return, please! */
  1298. X
  1299. X    /** now copy over the message... **/
  1300. X
  1301. X    while (fgets(buffer, SLEN, message) != NULL) {
  1302. X      if (buffer[0] == '[') {
  1303. X        if (strncmp(buffer, START_ENCODE, strlen(START_ENCODE))==0)
  1304. X          crypted = 1;
  1305. X        else if (strncmp(buffer, END_ENCODE, strlen(END_ENCODE))==0)
  1306. X          crypted = 0;
  1307. X        else if (strncmp(buffer, DONT_SAVE, strlen(DONT_SAVE)) == 0) {
  1308. X          fclose(message);
  1309. X          fclose(save);
  1310. X          chown(savename, userid, groupid);    
  1311. X          return(TRUE);
  1312. X        }
  1313. X      }
  1314. X      else if (crypted) {
  1315. X        if (! gotten_key++)
  1316. X          getkey(ON);
  1317. X        encode(buffer);
  1318. X      }
  1319. X      fputs(buffer, save);
  1320. X    }
  1321. X
  1322. X    fclose(message);
  1323. X    fclose(save);
  1324. X
  1325. X    /* make sure save file isn't owned by root! */
  1326. X    chown(savename, userid, groupid);    
  1327. X
  1328. X    return(TRUE);
  1329. X}
  1330. END_OF_src/savecopy.c
  1331. if test 4180 -ne `wc -c <src/savecopy.c`; then
  1332.     echo shar: \"src/savecopy.c\" unpacked with wrong size!?
  1333. fi
  1334. # end of overwriting check
  1335. fi
  1336. echo shar: Extracting \"utils/Makefile\" \(4197 characters\)
  1337. if test -f utils/Makefile ; then 
  1338.   echo shar: Will not over-write existing file \"utils/Makefile\"
  1339. else
  1340. sed "s/^X//" >utils/Makefile <<'END_OF_utils/Makefile'
  1341. X#
  1342. X#  Makefile for the Elm system utilities
  1343. X#
  1344. X#         (C) Copyright 1986, Dave Taylor
  1345. X#
  1346. X#  Last modification: Sept 15th, 1986
  1347. X
  1348. XSHELL=/bin/sh
  1349. X
  1350. XDEFINE= -DBSD
  1351. XLIB2  = -lcurses
  1352. X
  1353. XCFLAGS= -O -I../hdrs
  1354. XCC=    /bin/cc
  1355. XRM=     /bin/rm -f
  1356. XECHO=  /bin/echo
  1357. X
  1358. XOBJS=    ../bin/newalias ../bin/from ../bin/newmail ../bin/answer       \
  1359. X    ../bin/printmail ../bin/fastmail ../bin/readmsg                \
  1360. X    ../bin/checkalias ../bin/arepdaemon ../bin/autoreply ../bin/wnewmail \
  1361. X    ../bin/messages ../bin/trim-headers ../bin/listalias 
  1362. X
  1363. Xall: ${OBJS}
  1364. X
  1365. X../bin/newalias:  ../hdrs/defs.h newalias.c ../src/validname.o \
  1366. X    ../src/opt_utils.o
  1367. X    ${CC} ${CFLAGS} ${DEFINE} newalias.c ../src/validname.o \
  1368. X    ../src/opt_utils.o -o ../bin/newalias 
  1369. X
  1370. X../bin/from: from.c ../src/opt_utils.o ../src/string2.o
  1371. X    ${CC} ${CFLAGS} ${DEFINE} from.c ../src/opt_utils.o \
  1372. X    ../src/string2.o -o ../bin/from
  1373. X
  1374. X../bin/newmail: ../src/opt_utils.c newmail.c ../src/string2.o
  1375. X    ${CC} ${CFLAGS} ${DEFINE} newmail.c \
  1376. X    ../src/string2.o -o ../bin/newmail
  1377. X
  1378. X../bin/wnewmail: ../src/opt_utils.c wnewmail.c ../src/string2.o
  1379. X    ${CC} ${CFLAGS} ${DEFINE} ../src/opt_utils.o \
  1380. X    ../src/string2.o wnewmail.c -o ../bin/wnewmail
  1381. X
  1382. X../bin/listalias: listalias.c 
  1383. X    ${CC} ${CFLAGS} ${DEFINE} listalias.c -o ../bin/listalias
  1384. X
  1385. X../bin/answer: answer.c ../src/opt_utils.o
  1386. X    ${CC} ${CFLAGS} ${DEFINE} answer.c ../src/opt_utils.o -o ../bin/answer
  1387. X
  1388. X../bin/printmail: printmail.c ../src/opt_utils.o
  1389. X    ${CC} ${CFLAGS} ${DEFINE} printmail.c ../src/opt_utils.o \
  1390. X    -o ../bin/printmail
  1391. X
  1392. X../bin/fastmail: fastmail.c 
  1393. X    ${CC} ${CFLAGS} ${DEFINE} fastmail.c ../src/opt_utils.o \
  1394. X    -o ../bin/fastmail
  1395. X
  1396. X../bin/readmsg: readmsg.c ../src/getopt.o ../src/opt_utils.o ../src/string2.o
  1397. X    ${CC} ${CFLAGS} ${DEFINE} readmsg.c ../src/getopt.o ../src/string2.o \
  1398. X    ../src/opt_utils.o -o ../bin/readmsg
  1399. X
  1400. X../bin/arepdaemon: arepdaemon.c
  1401. X    ${CC} ${CFLAGS} ${DEFINE} arepdaemon.c -o ../bin/arepdaemon
  1402. X
  1403. X../bin/autoreply: autoreply.c ../src/opt_utils.o
  1404. X    ${CC} ${CFLAGS} ${DEFINE} autoreply.c ../src/opt_utils.o \
  1405. X    -o ../bin/autoreply
  1406. X
  1407. X../bin/checkalias: 
  1408. X    @echo ': Use /bin/sh' > ../bin/checkalias
  1409. X    @echo 'if [ "$$*" = "" ]; then' >> ../bin/checkalias
  1410. X    @echo '  echo Usage: checkalias alias \[or aliases\]' >>  \
  1411. X          ../bin/checkalias
  1412. X    @echo '  exit 1' >> ../bin/checkalias
  1413. X    @echo 'fi' >> ../bin/checkalias
  1414. X    @echo ' '  >> ../bin/checkalias
  1415. X    @echo 'exec elm -c $$*' >> ../bin/checkalias
  1416. X    @chmod +x ../bin/checkalias
  1417. X
  1418. X../bin/messages: 
  1419. X    @echo ': Use /bin/sh'                  > ../bin/messages
  1420. X    @echo 'if [ "$$2" != "" ]; then'         >> ../bin/messages
  1421. X    @echo '  echo Usage: messages \{folder-name\}'  >> ../bin/messages
  1422. X    @echo '  exit 1'                 >> ../bin/messages
  1423. X    @echo 'fi'                     >> ../bin/messages
  1424. X    @echo ' '                      >> ../bin/messages
  1425. X    @echo 'if [ "$$1" = "" ]; then'         >> ../bin/messages
  1426. X    @echo '  fname=$$MAIL'                 >> ../bin/messages
  1427. X    @echo '  optional="in your mailbox"'          >> ../bin/messages
  1428. X    @echo 'else'                     >> ../bin/messages
  1429. X    @echo '  fname=$$1'                >> ../bin/messages
  1430. X    @echo '  optional="in folder $$1"'         >> ../bin/messages
  1431. X    @echo 'fi'                           >> ../bin/messages
  1432. X    @echo ' '                    >> ../bin/messages
  1433. X    @echo 'mcount=`egrep "^From " $$fname | wc -l`' >> ../bin/messages
  1434. X    @echo ' '                    >> ../bin/messages
  1435. X    @echo 'if [ $$mcount = 1 ];then'        >> ../bin/messages
  1436. X    @echo '  echo There is $$mcount message $$optional' >> ../bin/messages
  1437. X    @echo 'else'                    >> ../bin/messages
  1438. X    @echo '  echo There are $$mcount messages $$optional' >> ../bin/messages
  1439. X    @echo 'fi'                    >> ../bin/messages
  1440. X    @echo ' '                    >> ../bin/messages
  1441. X    @echo 'exit 0'                    >> ../bin/messages
  1442. X    @chmod +x ../bin/messages
  1443. X
  1444. X../bin/trim-headers:
  1445. X    @cp trim-headers ../bin/trim-headers
  1446. X    @chmod +x ../bin/trim-headers
  1447. X
  1448. X../src/validname.o: ../src/validname.c ../hdrs/defs.h
  1449. X    @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} validname.c; cd ../utils)
  1450. X
  1451. X../src/opt_utils.o: ../src/opt_utils.c ../hdrs/defs.h
  1452. X    @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} opt_utils.c; cd ../utils)
  1453. X
  1454. X../src/getopt.o: ../src/getopt.c ../hdrs/defs.h
  1455. X    @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} getopt.c; cd ../utils)
  1456. X
  1457. X../src/string2.o: ../src/string2.c ../hdrs/defs.h
  1458. X    @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} string2.c; cd ../utils)
  1459. X
  1460. Xclean:
  1461. X    ${RM} *.o ${OBJS} ../bin/utils
  1462. X
  1463. Xlint:
  1464. X    lint -p -I../hdrs *.c > LINT.OUT
  1465. END_OF_utils/Makefile
  1466. if test 4197 -ne `wc -c <utils/Makefile`; then
  1467.     echo shar: \"utils/Makefile\" unpacked with wrong size!?
  1468. fi
  1469. # end of overwriting check
  1470. fi
  1471. echo shar: Extracting \"utils/Makefile.mstr\" \(4192 characters\)
  1472. if test -f utils/Makefile.mstr ; then 
  1473.   echo shar: Will not over-write existing file \"utils/Makefile.mstr\"
  1474. else
  1475. sed "s/^X//" >utils/Makefile.mstr <<'END_OF_utils/Makefile.mstr'
  1476. X#
  1477. X#  Makefile for the Elm system utilities
  1478. X#
  1479. X#         (C) Copyright 1986, Dave Taylor
  1480. X#
  1481. X#  Last modification: Sept 15th, 1986
  1482. X
  1483. XSHELL=/bin/sh
  1484. X
  1485. XDEFINE= >os-define<
  1486. XLIB2  = >lib2<
  1487. X
  1488. XCFLAGS= -O -I../hdrs
  1489. XCC=    >cc<
  1490. XRM=     >rm<
  1491. XECHO=  /bin/echo
  1492. X
  1493. XOBJS=    ../bin/newalias ../bin/from ../bin/newmail ../bin/answer       \
  1494. X    ../bin/printmail ../bin/fastmail ../bin/readmsg                \
  1495. X    ../bin/checkalias ../bin/arepdaemon ../bin/autoreply ../bin/wnewmail \
  1496. X    ../bin/messages ../bin/trim-headers ../bin/listalias 
  1497. X
  1498. Xall: ${OBJS}
  1499. X
  1500. X../bin/newalias:  ../hdrs/defs.h newalias.c ../src/validname.o \
  1501. X    ../src/opt_utils.o
  1502. X    ${CC} ${CFLAGS} ${DEFINE} newalias.c ../src/validname.o \
  1503. X    ../src/opt_utils.o -o ../bin/newalias 
  1504. X
  1505. X../bin/from: from.c ../src/opt_utils.o ../src/string2.o
  1506. X    ${CC} ${CFLAGS} ${DEFINE} from.c ../src/opt_utils.o \
  1507. X    ../src/string2.o -o ../bin/from
  1508. X
  1509. X../bin/newmail: ../src/opt_utils.c newmail.c ../src/string2.o
  1510. X    ${CC} ${CFLAGS} ${DEFINE} newmail.c \
  1511. X    ../src/string2.o -o ../bin/newmail
  1512. X
  1513. X../bin/wnewmail: ../src/opt_utils.c wnewmail.c ../src/string2.o
  1514. X    ${CC} ${CFLAGS} ${DEFINE} ../src/opt_utils.o \
  1515. X    ../src/string2.o wnewmail.c -o ../bin/wnewmail
  1516. X
  1517. X../bin/listalias: listalias.c 
  1518. X    ${CC} ${CFLAGS} ${DEFINE} listalias.c -o ../bin/listalias
  1519. X
  1520. X../bin/answer: answer.c ../src/opt_utils.o
  1521. X    ${CC} ${CFLAGS} ${DEFINE} answer.c ../src/opt_utils.o -o ../bin/answer
  1522. X
  1523. X../bin/printmail: printmail.c ../src/opt_utils.o
  1524. X    ${CC} ${CFLAGS} ${DEFINE} printmail.c ../src/opt_utils.o \
  1525. X    -o ../bin/printmail
  1526. X
  1527. X../bin/fastmail: fastmail.c 
  1528. X    ${CC} ${CFLAGS} ${DEFINE} fastmail.c ../src/opt_utils.o \
  1529. X    -o ../bin/fastmail
  1530. X
  1531. X../bin/readmsg: readmsg.c ../src/getopt.o ../src/opt_utils.o ../src/string2.o
  1532. X    ${CC} ${CFLAGS} ${DEFINE} readmsg.c ../src/getopt.o ../src/string2.o \
  1533. X    ../src/opt_utils.o -o ../bin/readmsg
  1534. X
  1535. X../bin/arepdaemon: arepdaemon.c
  1536. X    ${CC} ${CFLAGS} ${DEFINE} arepdaemon.c -o ../bin/arepdaemon
  1537. X
  1538. X../bin/autoreply: autoreply.c ../src/opt_utils.o
  1539. X    ${CC} ${CFLAGS} ${DEFINE} autoreply.c ../src/opt_utils.o \
  1540. X    -o ../bin/autoreply
  1541. X
  1542. X../bin/checkalias: 
  1543. X    @echo ': Use /bin/sh' > ../bin/checkalias
  1544. X    @echo 'if [ "$$*" = "" ]; then' >> ../bin/checkalias
  1545. X    @echo '  echo Usage: checkalias alias \[or aliases\]' >>  \
  1546. X          ../bin/checkalias
  1547. X    @echo '  exit 1' >> ../bin/checkalias
  1548. X    @echo 'fi' >> ../bin/checkalias
  1549. X    @echo ' '  >> ../bin/checkalias
  1550. X    @echo 'exec elm -c $$*' >> ../bin/checkalias
  1551. X    @chmod +x ../bin/checkalias
  1552. X
  1553. X../bin/messages: 
  1554. X    @echo ': Use /bin/sh'                  > ../bin/messages
  1555. X    @echo 'if [ "$$2" != "" ]; then'         >> ../bin/messages
  1556. X    @echo '  echo Usage: messages \{folder-name\}'  >> ../bin/messages
  1557. X    @echo '  exit 1'                 >> ../bin/messages
  1558. X    @echo 'fi'                     >> ../bin/messages
  1559. X    @echo ' '                      >> ../bin/messages
  1560. X    @echo 'if [ "$$1" = "" ]; then'         >> ../bin/messages
  1561. X    @echo '  fname=$$MAIL'                 >> ../bin/messages
  1562. X    @echo '  optional="in your mailbox"'          >> ../bin/messages
  1563. X    @echo 'else'                     >> ../bin/messages
  1564. X    @echo '  fname=$$1'                >> ../bin/messages
  1565. X    @echo '  optional="in folder $$1"'         >> ../bin/messages
  1566. X    @echo 'fi'                           >> ../bin/messages
  1567. X    @echo ' '                    >> ../bin/messages
  1568. X    @echo 'mcount=`egrep "^From " $$fname | wc -l`' >> ../bin/messages
  1569. X    @echo ' '                    >> ../bin/messages
  1570. X    @echo 'if [ $$mcount = 1 ];then'        >> ../bin/messages
  1571. X    @echo '  echo There is $$mcount message $$optional' >> ../bin/messages
  1572. X    @echo 'else'                    >> ../bin/messages
  1573. X    @echo '  echo There are $$mcount messages $$optional' >> ../bin/messages
  1574. X    @echo 'fi'                    >> ../bin/messages
  1575. X    @echo ' '                    >> ../bin/messages
  1576. X    @echo 'exit 0'                    >> ../bin/messages
  1577. X    @chmod +x ../bin/messages
  1578. X
  1579. X../bin/trim-headers:
  1580. X    @cp trim-headers ../bin/trim-headers
  1581. X    @chmod +x ../bin/trim-headers
  1582. X
  1583. X../src/validname.o: ../src/validname.c ../hdrs/defs.h
  1584. X    @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} validname.c; cd ../utils)
  1585. X
  1586. X../src/opt_utils.o: ../src/opt_utils.c ../hdrs/defs.h
  1587. X    @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} opt_utils.c; cd ../utils)
  1588. X
  1589. X../src/getopt.o: ../src/getopt.c ../hdrs/defs.h
  1590. X    @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} getopt.c; cd ../utils)
  1591. X
  1592. X../src/string2.o: ../src/string2.c ../hdrs/defs.h
  1593. X    @(cd ../src; ${CC} -c ${CFLAGS} ${DEFINE} string2.c; cd ../utils)
  1594. X
  1595. Xclean:
  1596. X    ${RM} *.o ${OBJS} ../bin/utils
  1597. X
  1598. Xlint:
  1599. X    lint -p -I../hdrs *.c > LINT.OUT
  1600. END_OF_utils/Makefile.mstr
  1601. if test 4192 -ne `wc -c <utils/Makefile.mstr`; then
  1602.     echo shar: \"utils/Makefile.mstr\" unpacked with wrong size!?
  1603. fi
  1604. # end of overwriting check
  1605. fi
  1606. echo shar: Extracting \"utils/autoreply.c\" \(4689 characters\)
  1607. if test -f utils/autoreply.c ; then 
  1608.   echo shar: Will not over-write existing file \"utils/autoreply.c\"
  1609. else
  1610. sed "s/^X//" >utils/autoreply.c <<'END_OF_utils/autoreply.c'
  1611. X/**            autoreply.c            **/
  1612. X
  1613. X/** This is the front-end for the autoreply system, and performs two 
  1614. X    functions: it either adds the user to the list of people using the
  1615. X    autoreply function (starting the daemon if no-one else) or removes
  1616. X    a user from the list of people.
  1617. X
  1618. X    Usage:  autoreply filename
  1619. X        autoreply "off"
  1620. X    or  autoreply        [to find current status]
  1621. X    
  1622. X    (C) 1986, Dave Taylor
  1623. X**/
  1624. X
  1625. X#include <stdio.h>
  1626. X#include <errno.h>
  1627. X#include <sys/types.h>
  1628. X#include <sys/stat.h>
  1629. X
  1630. X#include "defs.h"
  1631. X
  1632. Xstatic char ident[] = { WHAT_STRING };
  1633. X
  1634. X#define  tempdir    "/tmp/arep"        /* file prefix          */
  1635. X#define  autoreply_file    "/etc/autoreply.data"   /* autoreply data file  */
  1636. X
  1637. Xextern   int errno;                /* system error code    */
  1638. Xchar     username[NLEN];            /* login name of user   */
  1639. X
  1640. Xmain(argc, argv)
  1641. Xint    argc;
  1642. Xchar *argv[];
  1643. X{
  1644. X    char filename[SLEN];
  1645. X
  1646. X    if (argc > 2) {
  1647. X      printf("Usage: %s <filename>\tto start autoreply,\n", argv[0]);
  1648. X      printf("       %s off\t\tto turn off autoreply\n", argv[0]);
  1649. X      printf("   or  %s    \t\tto check current status\n", argv[0]);
  1650. X      exit(1);
  1651. X    }
  1652. X
  1653. X    (void) cuserid(username);
  1654. X
  1655. X    if (argc == 1 || strcmp(argv[1], "off") == 0) 
  1656. X      remove_user((argc == 1));
  1657. X    else {
  1658. X      strcpy(filename, argv[1]);
  1659. X      if (access(filename,READ_ACCESS) != 0) {
  1660. X        printf("Error: Can't read file '%s'\n", filename);
  1661. X        exit(1);
  1662. X      }
  1663. X      
  1664. X      if (filename[0] != '/') /* prefix home directory */
  1665. X        sprintf(filename,"%s/%s", getenv("HOME"), argv[1]);
  1666. X
  1667. X      add_user(filename);
  1668. X    }
  1669. X
  1670. X    exit(0);
  1671. X}
  1672. X
  1673. Xremove_user(stat_only)
  1674. Xint stat_only;
  1675. X{
  1676. X    /** Remove the user from the list of currently active autoreply 
  1677. X        people.  If 'stat_only' is set, then just list the name of
  1678. X        the file being used to autoreply with, if any. **/
  1679. X
  1680. X    FILE *temp, *repfile;
  1681. X    char  tempfile[SLEN], user[SLEN], filename[SLEN];
  1682. X    int   c, copied = 0, found = 0;
  1683. X    long  filesize, bytes();
  1684. X
  1685. X    if (! stat_only) {
  1686. X      sprintf(tempfile, "%s.%06d", tempdir, getpid());
  1687. X
  1688. X      if ((temp = fopen(tempfile, "w")) == NULL) {
  1689. X        printf("Error: couldn't open tempfile '%s'.  Not removed\n",
  1690. X            tempfile);
  1691. X        exit(1);
  1692. X      }
  1693. X    }
  1694. X
  1695. X    if ((repfile = fopen(autoreply_file, "r")) == NULL) {
  1696. X      if (stat_only) {
  1697. X        printf("You're not currently autoreplying to mail.\n");
  1698. X        exit(0);
  1699. X      }
  1700. X      printf("No-one is autoreplying to their mail!\n");
  1701. X      exit(0);
  1702. X    }
  1703. X
  1704. X    /** copy out of real replyfile... **/
  1705. X
  1706. X    while (fscanf(repfile, "%s %s %ld", user, filename, &filesize) != EOF) 
  1707. X
  1708. X      if (strcmp(user, username) != 0) {
  1709. X        if (! stat_only) {
  1710. X          copied++;
  1711. X          fprintf(tempfile, "%s %s %ld\n", user, filename, filesize);
  1712. X        }
  1713. X      }
  1714. X      else {
  1715. X        if (stat_only) {
  1716. X          printf("You're currently autoreplying to mail with the file %s\n",              filename); 
  1717. X          exit(0);
  1718. X        }
  1719. X        found++;
  1720. X      }
  1721. X
  1722. X    fclose(temp);
  1723. X    fclose(repfile);
  1724. X
  1725. X    if (! found) {
  1726. X      printf("You're not currently autoreplying to mail%s\n",
  1727. X          stat_only? "." : "!");
  1728. X      if (! stat_only)
  1729. X        unlink(tempfile);
  1730. X      exit(! stat_only);
  1731. X    }
  1732. X
  1733. X    /** now copy tempfile back into replyfile **/
  1734. X
  1735. X    if (copied == 0) {    /* removed the only person! */
  1736. X      unlink(autoreply_file);
  1737. X    }
  1738. X    else {            /* save everyone else   */
  1739. X      
  1740. X      if ((temp = fopen(tempfile,"r")) == NULL) {
  1741. X        printf("Error: couldn't reopen tempfile '%s'.  Not removed.\n",
  1742. X            tempfile);
  1743. X        unlink(tempfile);
  1744. X        exit(1);
  1745. X      }
  1746. X
  1747. X      if ((repfile = fopen(autoreply_file, "w")) == NULL) {
  1748. X        printf(
  1749. X          "Error: couldn't reopen autoreply file for writing!  Not removed.\n");
  1750. X        unlink(tempfile);
  1751. X        exit(1);
  1752. X      }
  1753. X
  1754. X      while ((c = getc(temp)) != EOF)
  1755. X        putc(c, repfile);
  1756. X
  1757. X      fclose(temp);
  1758. X      fclose(repfile);
  1759. X    
  1760. X    }
  1761. X    unlink(tempfile);
  1762. X
  1763. X    if (found > 1)
  1764. X      printf("Warning: your username appeared %d times!!   Removed all\n", 
  1765. X          found);
  1766. X    else
  1767. X      printf("You've been removed from the autoreply table.\n");
  1768. X}
  1769. X
  1770. Xadd_user(filename)
  1771. Xchar *filename;
  1772. X{
  1773. X    /** add the user to the autoreply file... **/
  1774. X
  1775. X    FILE *repfile;
  1776. X    char  mailfile[SLEN];
  1777. X    long  bytes();
  1778. X
  1779. X    if ((repfile = fopen(autoreply_file, "a")) == NULL) {
  1780. X      printf("Error: couldn't open the autoreply file!  Not added\n");
  1781. X      exit(1);
  1782. X    }
  1783. X    
  1784. X    sprintf(mailfile,"%s/%s", mailhome, username);
  1785. X
  1786. X    fprintf(repfile,"%s %s %ld\n", username, filename, bytes(mailfile));
  1787. X
  1788. X    fclose(repfile);
  1789. X
  1790. X    printf("You've been added to the autoreply system.\n");
  1791. X}
  1792. X
  1793. X
  1794. Xlong
  1795. Xbytes(name)
  1796. Xchar *name;
  1797. X{
  1798. X    /** return the number of bytes in the specified file.  This
  1799. X        is to check to see if new mail has arrived....  **/
  1800. X
  1801. X    int ok = 1;
  1802. X    extern int errno;    /* system error number! */
  1803. X    struct stat buffer;
  1804. X
  1805. X    if (stat(name, &buffer) != 0)
  1806. X      if (errno != 2)
  1807. X       exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name));
  1808. X      else
  1809. X        ok = 0;
  1810. X    
  1811. X    return(ok ? buffer.st_size : 0L);
  1812. X}
  1813. END_OF_utils/autoreply.c
  1814. if test 4689 -ne `wc -c <utils/autoreply.c`; then
  1815.     echo shar: \"utils/autoreply.c\" unpacked with wrong size!?
  1816. fi
  1817. # end of overwriting check
  1818. fi
  1819. echo shar: End of archive 3 \(of 19\).
  1820. cp /dev/null ark3isdone
  1821. DONE=true
  1822. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
  1823.     if test ! -f ark${I}isdone ; then
  1824.     echo shar: You still need to run archive ${I}.
  1825.     DONE=false
  1826.     fi
  1827. done
  1828. if test "$DONE" = "true" ; then
  1829.     echo You have unpacked all 19 archives.
  1830.     echo "See the Instructions file"
  1831.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1832. fi
  1833. ##  End of shell archive.
  1834. exit 0
  1835.